package com.liu.project.controller;

import com.liu.project.kmeans.ClusterModel;
import com.liu.project.kmeans.kmeans;
import com.liu.project.pojo.Certificate;
import com.liu.project.pojo.ProfessionalOrientation;
import com.liu.project.service.CertificateService;
import com.liu.project.service.ProfessionService;

import com.liu.project.utils.JaroWinklerDistance;
import com.liu.project.utils.Message;
import com.liu.project.utils.RedisUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.security.core.parameters.P;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import java.util.*;

/**
 * @program: project
 * @description:
 * @author: 86187
 * @create: 2022-03-20 15:58
 **/

@Api(tags = "根据职业关键字获取相关职业名称，根据职业名称获取向相关证书")
@Controller
@RequestMapping("/api/profession")
public class ProfessionController {

    @Autowired
    ProfessionService professionService;

    @Autowired
    JaroWinklerDistance jaroWinklerDistance;

    @Autowired
    private RedisUtil redisUtil;

    @Autowired
    private kmeans kmeans;

    @Autowired
    private CertificateService service;

    @PostMapping("/")
    @ResponseBody
    public Message<List<ProfessionalOrientation>> getAllSubject(){
        List<ProfessionalOrientation> all = professionService.getAll();
        return new Message<List<ProfessionalOrientation>>(200,"请求成功",all);
    }

    @ApiOperation("根据关键字返回相似度最高的四个职业列表")
    @PostMapping("/search")
    @ApiResponse(code = 200,message = "请求成功",response = Message.class)
    @ResponseBody
    public Message<List<ProfessionalOrientation>> getProByProK(@RequestParam("prokey") String prokey){
        List<ProfessionalOrientation> all = professionService.getAll();
        Map<ProfessionalOrientation, Float> dis = new HashMap<ProfessionalOrientation,Float>();//存放 key为 职业对象，value是职业名和key的相似度
        for (ProfessionalOrientation pro : all) {
            float distance = jaroWinklerDistance.getJaroWinklerDistance(pro.getProfessionalName(), prokey);
            dis.put(pro,distance);
        }
        List<Map.Entry<ProfessionalOrientation, Float>> entries = new ArrayList<>(dis.entrySet());
        Collections.sort(entries, new Comparator<Map.Entry<ProfessionalOrientation, Float>>() {
            //是结果降序排序
            @Override
            public int compare(Map.Entry<ProfessionalOrientation, Float> o1, Map.Entry<ProfessionalOrientation, Float> o2) {
                return o2.getValue().compareTo(o1.getValue());
            }
        });
        if (entries.get(0).getValue()<=0) return new Message(0,"无该辞职");
        List<ProfessionalOrientation> proList =new ArrayList<>();
        for (Map.Entry<ProfessionalOrientation, Float> entry : entries.subList(0,4)) {
            proList.add(entry.getKey());
        }

        return new Message<List<ProfessionalOrientation>>(200,"请求成功",new ArrayList<>(proList));
    }

    @PostMapping("/search2")
    @ApiOperation("根据职业名称返回相关的证书列表")
    @ApiResponse(code = 200,message = "请求成功",response = Message.class)
    @ResponseBody
    public Message<List<Certificate>> getCertiByProK(@RequestParam("proName") String proName){
        Message<List<ProfessionalOrientation>> proByProK = getProByProK(proName);
        for (ProfessionalOrientation datum : proByProK.getData()) {
            int tem=0;
            if (datum.getProfessionalName().equals(proName))  tem++;
            if (tem<1) return new Message(0,"无此职业");

        }
        double pfvalueByName = professionService.getPfvalueByName(proName);
        HashSet<Certificate> tempList = new HashSet<>();
        if (redisUtil.get("y:"+pfvalueByName)==null){//当缓存没有是进行计算并存入缓存，如果有，怎直接取出
            //根据查出的职业量化值 查找对应证书
            ClusterModel o = (ClusterModel)redisUtil.get("kmeans");

            for (int i = 0; i < o.originalCenters.length; i++) {
                double[] center=o.originalCenters[i];
                if (center[o.data.dim-1]== kmeans.normalize_y(pfvalueByName)){//找到职业值相同的聚类的中心点
                    int index = o.labels[o.perm[o.start[i]]];//找到该中心的证书
                    int counts = o.centerCounts[index];
                    for (int y1 = o.start[i]; y1 < counts; y1++) {
                        Certificate certificateById = service.findCertificateById(Integer.parseInt(o.iden0.get(o.perm[y1])));
                        tempList.add(certificateById);
                    }
                }
            }
          redisUtil.set("y:"+pfvalueByName,tempList);
       }else tempList= (HashSet<Certificate>) redisUtil.get("y:"+pfvalueByName);

        return new Message<List<Certificate>>(200,"请求成功",new ArrayList<Certificate>(tempList));
    }
}
